package com.cloudlinkscm.base.authcenter.service.impl;

import com.cloudlinkscm.base.authcenter.common.RedisManager;
import com.cloudlinkscm.base.authcenter.dao.LoginLogDao;
import com.cloudlinkscm.base.authcenter.dao.UserAccountDao;
import com.cloudlinkscm.base.authcenter.domain.AbstractUserAccountManager;
import com.cloudlinkscm.base.authcenter.exception.UserAccountNoCacheException;
import com.cloudlinkscm.base.authcenter.exception.UserAccountNotFindException;
import com.cloudlinkscm.base.authcenter.model.UserAccount;
import com.cloudlinkscm.base.authcenter.model.dto.*;
import com.cloudlinkscm.base.authcenter.service.AuthcService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

/**
 * @author : tac
 * @date : 28/07/2017
 */

@Service
public class AuthcServiceImpl implements AuthcService {

    @Autowired
    private RedisManager redisManager;
    @Autowired
    private UserAccountDao dao;
    @Autowired
    private LoginLogDao loginLogDao;
    @Autowired
    private AbstractUserAccountManager userAccountManager;


    @Override
    public AccessToken doAuthenticate(AuthenticationInfo info) {

	    UserAccount userAccount = dao.selectByUsername(info.getAccount());
	    if (userAccount == null) {
	    	throw new UserAccountNotFindException();
	    }

	    String tokenPassword = info.getPassword() + userAccount.getSalt();
	    UsernamePasswordToken token = new UsernamePasswordToken(info.getAccount(), tokenPassword);
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isAuthenticated()){
            subject.login(token);
        }
        UserAccount account = (UserAccount)subject.getPrincipal();

	    // TODO: 登录日志【sin】
	    return redisManager.cacheUserAccount(newToken(), account);
    }

	@Override
	public UserAccountDTO getAccount(String token) {
    	UserAccount userAccount = redisManager.getUserAccount(token);
    	if (userAccount == null) {
    		throw new UserAccountNoCacheException();
	    }
    	UserAccountDTO userAccountDTO = new UserAccountDTO();
    	BeanUtils.copyProperties(userAccount, userAccountDTO);
		userAccountDTO.setAccountId(userAccount.getId());
        return userAccountDTO;
    }

	@Override
	public List<ResourceTree> accountResource(String token) {
    	UserAccountDTO userAccountDTO = getAccount(token);
		return userAccountManager.accountResource(userAccountDTO.getAccountId());
	}

	@Override
	public AuthenticationWebInfo doAuthenticateWeb(AuthenticationInfo info) {
		AccessToken accessToken = doAuthenticate(info);
		List<ResourceTree> resourceTrees = accountResource(accessToken.getToken());
		return new AuthenticationWebInfo(accessToken, resourceTrees);
	}

	public static String newToken() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
